﻿#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include "itcast_asn1_der.h"
#include "itcastderlog.h"

typedef struct _Teacher
{
	char name[64];
	int age;
	char* p;
	int plen;
}Teacher;

void freeTeacherDer(Teacher** pTeacher)
{
	if (pTeacher == NULL)
	{
		return;
	}
	if (*pTeacher != NULL)
	{
		if ((*pTeacher)->p != NULL)
		{
			free((*pTeacher)->p);
			(*pTeacher)->p = NULL;
		}
		free(*pTeacher);
		*pTeacher = NULL;
	}
}

//1.传入，传出，传入传出；
int TeacherEncode(Teacher* pTeacher, unsigned char** out, int* outlen)
{
	/*unsigned char* tmp = malloc(32);
	strcpy(tmp, "xxxxxyyyyy");
	*out = tmp;
	*outlen = strlen(tmp);*/

	int					ret = 0;
	ITCAST_ANYBUF* pTmp = NULL, * pHeadBuf = NULL;
	ITCAST_ANYBUF* pTmpBuf = NULL;
	ITCAST_ANYBUF* pOutData = NULL;

	unsigned char* tmpOut = NULL;
	int					tmpOutLen = 0;

	//2.将char*类型的name转换成ITCAST_ANYBUF类型；
	ret = DER_ITCAST_String_To_AnyBuf(&pTmpBuf, pTeacher->name, strlen(pTeacher->name));
	if (ret != 0)
	{
		printf("DER_ITCAST_String_To_AnyBuf error: %d\n", ret);
		return ret;
	}

	//3.编码name --> TLV；
	ret = DER_ItAsn1_WritePrintableString(pTmpBuf, &pHeadBuf);
	if (ret != 0)
	{
		DER_ITCAST_FreeQueue(pTmpBuf);
		printf("DER_ItAsn1_WritePrintableString error: %d\n", ret);
		return ret;
	}
	DER_ITCAST_FreeQueue(pTmpBuf);

	pTmp = pHeadBuf;
	//4.编码age；
	ret = DER_ItAsn1_WriteInteger(pTeacher->age, &(pTmp->next));
	if (ret != 0)
	{
		DER_ITCAST_FreeQueue(pHeadBuf);
		printf("DER_ItAsn1_WriteInteger error: %d\n", ret);
		return ret;
	}

	pTmp = pTmp->next;
	//5.编码p，char*;
	ret = EncodeChar(pTeacher->p, pTeacher->plen, &(pTmp->next));
	if (ret != 0)
	{
		DER_ITCAST_FreeQueue(pHeadBuf);
		printf("EncodeChar error: %d\n", ret);
		return ret;
	}

	pTmp = pTmp->next;
	//6.编码plen;
	ret = DER_ItAsn1_WriteInteger(pTeacher->plen, &(pTmp->next));
	if (ret != 0)
	{
		DER_ITCAST_FreeQueue(pHeadBuf);
		printf("DER_ItAsn1_WriteInteger error: %d\n", ret);
		return ret;
	}

	//7.编码大结构体；
	ret = DER_ItAsn1_WriteSequence(pHeadBuf, &pOutData);
	if (ret != 0)
	{
		DER_ITCAST_FreeQueue(pHeadBuf);
		printf("DER_ItAsn1_WriteSequence error: %d\n", ret);
		return ret;
	}

	//*out = pOutData->pData;
	*out = (unsigned char*)malloc(pOutData->dataLen);
	if (*out == NULL)
	{
		ret = 2;
		DER_ITCAST_FreeQueue(pOutData);
		printf("func TeacherEncode() malloc err: %d\n", ret);
		return ret;
	}
	//17.把运算结果copy到新分配的内存块中；
	memcpy(*out, pOutData->pData, pOutData->dataLen);
	*outlen = pOutData->dataLen;

	return 0;
}

int mywritefileDer(unsigned char* buf, int len)
{
	FILE* fp = NULL;
	fp = fopen("D:/itcast/teacher.ber", "wb+");
	if (fp == NULL)
	{
		printf("fopen file error \n");
		return -1;
	}
	fwrite(buf, 1, len, fp);
	fclose(fp);
	return 0;
}

int TeacherDecode(unsigned char* indata, int inLen, Teacher** pStruct)
{
	int					ret = 0;
	ITCAST_ANYBUF* pTmp = NULL, * pHead = NULL;
	ITCAST_ANYBUF* pOutData = NULL;
	ITCAST_ANYBUF* tmpAnyBuf = NULL;

	Teacher* pStructTeacher = NULL;

	//18.把c语言buf，转成ITCAST_ANYBUF；
	/*
		tmpAnyBuf = (ITCAST_ANYBUF*)malloc(sizeof(ITCAST_ANYBUF));
		if (tmpAnyBuf == NULL)
		{
			ret = 1;
			printf("func TeacherEncode malloc error: %d\n", ret);
			return ret;
		}
		memset(tmpAnyBuf, 0, sizeof(ITCAST_ANYBUF));

		tmpAnyBuf->pData = (unsigned char*)malloc(inLen);
		if (tmpAnyBuf->pData == NULL)
		{
			DER_ITCAST_FreeQueue(tmpAnyBuf);
			ret = 2;
			printf("func TeacherEncode malloc error: %d\n", ret);
			return ret;
		}
		memcpy(tmpAnyBuf->pData, indata, inLen);
		tmpAnyBuf->dataLen = inLen;
	*/

	//13.转码BER报文，unsigned char* --> ITCAST_ANYBUF；
	ret = DER_ITCAST_String_To_AnyBuf(&tmpAnyBuf, indata, inLen);
	if (ret != 0)
	{
		if (tmpAnyBuf != NULL)
		{
			DER_ITCAST_FreeQueue(tmpAnyBuf);
		}
		printf("Decode DER_ITCAST_String_To_AnyBuf error: %d\n", ret);
		return ret;
	}

	//8.解码大Teacher结构体；
	ret = DER_ItAsn1_ReadSequence(tmpAnyBuf, &pHead);
	if (ret != 0)
	{
		if (tmpAnyBuf != NULL)
			DER_ITCAST_FreeQueue(tmpAnyBuf);

		printf("Decode DER_ItAsn1_ReadSequence error: %d\n", ret);
		return ret;
	}
	DER_ITCAST_FreeQueue(tmpAnyBuf);

	//15.给Teacher结构体malloc空间；
	pStructTeacher = (Teacher*)malloc(sizeof(Teacher));
	if (pStructTeacher == NULL)
	{
		DER_ITCAST_FreeQueue(pHead);
		ret = -1;
		printf("Teacher malloc error: %d\n", ret);
		return ret;
	}
	memset(pStructTeacher, 0, sizeof(Teacher));

	pTmp = pHead;
	//9.解码name；
	ret = DER_ItAsn1_ReadPrintableString(pTmp, &pOutData);
	if (ret != 0)
	{
		DER_ITCAST_FreeQueue(pHead);
		freeTeacherDer(&pStructTeacher);
		printf("Decode DER_ItAsn1_ReadPrintableString name error: %d\n", ret);
		return ret;
	}
	//14.ppPrintString->pData; --> name
	memcpy(pStructTeacher->name, pOutData->pData, pOutData->dataLen);

	pTmp = pTmp->next;
	DER_ITCAST_FreeQueue(pOutData);
	//10.解码age；
	ret = DER_ItAsn1_ReadInteger(pTmp, &(pStructTeacher->age));
	if (ret != 0)
	{
		DER_ITCAST_FreeQueue(pHead);
		freeTeacherDer(&pStructTeacher);
		printf("Decode DER_ItAsn1_ReadInteger age error: %d\n", ret);
		return ret;
	}

	pTmp = pTmp->next;
	//11.解码p；
	ret = DER_ItAsn1_ReadPrintableString(pTmp, &pOutData);
	if (ret != 0)
	{
		DER_ITCAST_FreeQueue(pHead);
		freeTeacherDer(&pStructTeacher);
		printf("Decode DER_ItAsn1_ReadPrintableString p error: %d\n", ret);
		return ret;
	}
	//16.给Teacher结构体中的p指针开辟空间；
	pStructTeacher->p = (char*)malloc(pOutData->dataLen + 1);
	if (pStructTeacher->p == NULL)
	{
		DER_ITCAST_FreeQueue(pHead);
		freeTeacherDer(&pStructTeacher);
		ret = -2;
		printf("Teacher->p malloc error: %d\n", ret);
		return ret;
	}
	memcpy(pStructTeacher->p, pOutData->pData, pOutData->dataLen);
	//pStructTeacher->p[pOutData->dataLen - 4] = 'R';//编码 != 解码
	pStructTeacher->p[pOutData->dataLen] = '\0';

	pTmp = pTmp->next;
	DER_ITCAST_FreeQueue(pOutData);
	//12.解码plen；
	ret = DER_ItAsn1_ReadInteger(pTmp, &(pStructTeacher->plen));
	if (ret != 0)
	{
		DER_ITCAST_FreeQueue(pHead);
		freeTeacherDer(&pStructTeacher);
		printf("Decode DER_ItAsn1_ReadInteger plen error: %d\n", ret);
		return ret;
	}

	*pStruct = pStructTeacher;
	return 0;
}

//main342：教师结构体编解码
int main342()
{
	int ret = 0;

	Teacher t1;
	Teacher* tempTeacher = NULL;
	unsigned char* myOut = NULL;
	int myOutlen = 0;

	t1.age = 10;
	//strcpy(t1.name, "xxxxxffff");
	strcpy(t1.name, "myName");
	t1.p = malloc(64);
	strcpy(t1.p, "aaaabbbb");
	t1.plen = strlen(t1.p);

	printf("before -- myout = %s, myOutLen = %d\n", myOut, myOutlen);
	TeacherEncode(&t1, &myOut, &myOutlen);

	mywritefileDer(myOut, myOutlen);
	printf("after -- myout = %s, myOutLen = %d\n", myOut, myOutlen);

	printf("hello....\n");

	/*before -- myout = (null), myOutLen = 0
	after -- myout = xxxxxyyyyy, myOutLen = 10
	hello....
	*/

	//-->

	/*before -- myout = (null), myOutLen = 0
	after -- myout = 0myName
	aaaabbbbN, myOutLen = 26
	hello....*/

	TeacherDecode(myOut, myOutlen, &tempTeacher);
	if (strcmp(t1.name, tempTeacher->name) == 0 && memcmp(t1.p, tempTeacher->p, tempTeacher->plen) == 0)
	{
		printf("编码 == 解码 \n");//编码 == 解码
	}
	else
	{
		printf("编码 != 解码 \n");
	}
	freeTeacherDer(&tempTeacher);

	system("pause");
	return EXIT_SUCCESS;
}